let game = {
  gameName: 'shequ'
};
import { TweenLite } from 'gsap';
game.tween = function(obj, time, option) {
  //TweenLite.to(this, 0.3, { loadingOpacity: 0, ease: Linear.easeIn });
  if (option.ease) {
    delete option.ease;
  }
  return TweenLite.to(obj, time, option);
};
import md5 from './md5.js'
game.md5 = function(s) {
  return md5.hex_md5(s);
};
import { io } from "socket.io-client";
game.io = io()
//接口地址
game.apiurl = 'local';
//执行云函数
game.call = function(action, request) {
  return new Promise((resolve, reject) => {
	  console.log('request ======', action, request)
    if (!request) {
      request = {};
    }
    request.game = game.gameName;
    request.udid = game.udid();
    if (game.apiurl == 'uniCloud') {
      uniCloud.callFunction({
          name: 'onez-game',
          data: {
            action: action,
            request: request
          }
        })
        .then((res) => {
          if (res.error) {
            resolve(res);
          } else {
            resolve(res.result);
          }
        });
    } else if (game.apiurl.indexOf('http://') == 0 || game.apiurl.indexOf('https://') == 0) {
      request.action = action;
      game.request(request).then(resolve);
    } else {
      if (action == 'scene') {
        resolve(require('./../data/scene.json'));
      } else if (action == 'role') {
        let role = require('./../data/role.json');
        role.nickname = (Math.random() + '').split('.')[1];
        resolve(role);
      }
    }
  });
};
//延时
game.delay = function(sec) {
  return new Promise((resolve, reject) => {
    setTimeout(function() {
      resolve();
    }, sec * 1000);
  });
};
//延时
game.wait = function(that) {
  return new Promise((resolve, reject) => {
    that.$forceUpdate();
    that.$nextTick(() => {
      resolve();
    });
  });
};
//等待用户处理或超时
game.waitReturn = function(sec, checkFunc) {
  return new Promise((resolve, reject) => {
    let timer;
    let curSec = 0;
    timer = setInterval(async() => {
      curSec++;
      if (checkFunc) {
        if (await checkFunc(curSec)) {
          clearInterval(timer);
          resolve(true);
          return;
        }
      }
      if (curSec >= sec) {
        clearInterval(timer);
        resolve(false);
        return;
      }
    }, 1000);
  });
};
game.date = function(format, time) {
  var date;
  if (time) {
    date = new Date(time * 1000);
  } else {
    date = new Date();
  }
  format = format || 'MMddhhmm';
  var o = {
    "M+": date.getMonth() + 1, //month
    "d+": date.getDate(), //day
    "h+": date.getHours(), //hour
    "m+": date.getMinutes(), //minute
    "s+": date.getSeconds(), //second
    "q+": Math.floor((date.getMonth() + 3) / 3), //quarter
    "S": date.getMilliseconds() //millisecond
  };

  if (/(y+)/.test(format)) {
    format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
  }

  for (var k in o) {
    if (new RegExp("(" + k + ")").test(format)) {
      format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] :
        ("00" + o[k]).substr(("" + o[k]).length));
    }
  }
  return format;
};
game.inUniApp = function() {
  if (typeof uni != 'undefined') {
    return true;
  }
  return false;
};
//播放背景音乐
let musicAudioContext = null;
game.playMusic = function(url) {
  if (!musicAudioContext) {
    if (game.inUniApp()) {
      musicAudioContext = uni.createInnerAudioContext();
    } else {
      musicAudioContext = new Audio();
    }
    musicAudioContext.loop = true;
    musicAudioContext.autoplay = true;
  }
  musicAudioContext.src = url;
};
//播放音效
game.playSound = function(url) {
  var audio;
  if (game.inUniApp()) {
    audio = uni.createInnerAudioContext();
  } else {
    audio = new Audio();
  }
  audio.loop = false;
  audio.autoplay = true;
  audio.src = url;

};
let getImageInfo_ready = true;

function waitGetImageInfo() {
  return new Promise((resolve, reject) => {
    if (getImageInfo_ready) {
      resolve();
      return;
    }
    let timer;
    timer = setInterval(() => {
      if (getImageInfo_ready) {
        clearInterval(timer);
        resolve();
      }
    }, 100);
  });
};
//获取图片信息
game.getImageInfo = function(url) {
  return new Promise((resolve, reject) => {
    if (game.inUniApp()) {
      waitGetImageInfo().then(() => {
        getImageInfo_ready = false;
        uni.getImageInfo({
          src: url,
          success: function(image) {
            getImageInfo_ready = true;
            resolve(image);
          },
          fail(res) {
            getImageInfo_ready = true;
            resolve({
              status: 'error',
              error: res.errMsg,
              width: 0,
              height: 0
            });
          }
        });
      });
    } else {
      var img = new Image();
      img.onload = function() {
        resolve({
          status: 'success',
          width: img.width,
          height: img.height
        });
      };
      img.onerror = function(res) {
        resolve({
          status: 'error',
          error: res,
          width: 0,
          height: 0
        });
      };
      img.src = url;
    }
  });
};
//加载资源
game.allRes = {};
game.loadRes = function(url, type) {
  return new Promise((resolve, reject) => {
    if (game.allRes[url]) {
      resolve(game.allRes[url]);
      return;
    }
    var t = url.split('.');
    var ext = t[t.length - 1];
    if (ext == 'json') {
      type = 'json';
    }
    var type = type || 'image';
    if (type == 'image') {
      game.getImageInfo(url).then((res) => {
        game.allRes[url] = res;
        resolve(game.allRes[url]);
      });
    } else {
      resolve({});
    }
  });
};
//寻路
game.find_path = function(start, end, map, marker) {
  var marker = marker || 1;
  var open = [];
  var close = [];
  var s_p = start;
  var e_p = end;
  var map_arr = map;
  var tra_marker = marker;
  var G = 0;
  var H = 0;
  var F = 0;
  var times = 0;
  //加入起始节点  [x, y , G ,F ,father]  
  open.push([s_p[0], s_p[1], 0, (Math.abs(e_p[0] - s_p[0]) + Math.abs(e_p[1] - s_p[1])), null]);

  function find(obj) {
    //重拍，取最小的一个  
    var count = 0;
    for (var i = obj[0] - 1, ilen = i + 3; i < ilen; i++) {
      for (var j = obj[1] - 1, jlen = j + 3; j < jlen; j++) {
        //遍历周围八节点,排除自己  
        if (i == obj[0] && j == obj[1])
          continue;
        //排除穿越的情况  
        if (!((i == obj[0]) || (j == obj[1])) && (map_arr[i] && map_arr[obj[0]] && map_arr[i][obj[1]] != tra_marker &&
            map_arr[obj[0]][j] != tra_marker)) {
          continue;
        }
        if (i == e_p[0] && j == e_p[1]) {
          open.push([i, j, G, F, obj]);
          var ways = [];
          var ele = obj;
          do {
            ways.unshift(ele);
            ele = ele[4];
          } while (ele != null && ele[4] != null);
          return ways;
        }

        if (map_arr[i] && map_arr[i][j] && map_arr[i][j] == tra_marker && game.is_exist(open, [i, j]) == -1 && game
          .is_exist(close, [i, j]) == -1) {
          G = (i == obj[0]) || (j == obj[1]) ? obj[2] + 1.0 : obj[2] + 1.4;
          H = Math.sqrt((e_p[0] - i) * (e_p[0] - i) + (e_p[1] - j) * (e_p[1] - j));
          F = G + H;
          open.push([i, j, G, F, obj]);
          count++;
        }
      }
    }
    close.push(open.shift());
    var o;
    if (open[0] && open[0][4] == obj[4]) {
      o = count == 0 ? game.get_other(open, obj) : (game.arr_sort(open), open[0]);
    } else {
      o = (game.arr_sort(open), open[0]);
    }
    if (o) {
      times++;
      if (times >= 1000) {
        return [];
      }
      return find(o);
    } else {
      return [];
    }
  }
  return find(open[0]);
};
game.get_other = function(arr, o) {
  var a = [];
  for (var i = 0; i < arr.length; i++) {
    if (o && arr[i][4] == o[4]) {
      return arr[i];
    }
  }
  if (o[4]) {
    times++;
    if (times >= 200) {
      return [];
    }
    return game.get_other(o[4]);
  } else {
    return [];
  }
};
game.arr_sort_s = function(a, b) {
  return a[3] - b[3];
};
game.arr_sort = function(arr) {
  arr.sort(game.arr_sort_s);
}
game.is_exist = function(arr, p) {
  for (var i = 0; i < arr.length; i++) {
    if (arr[i][0] == p[0] && arr[i][1] == p[1]) {
      return i;
    }
  }
  return -1;
};
//唯一标识
var udid_ = '';
game.udid = function() {
  if (udid_ != '') {
    return udid_;
  }
  udid_ = game.getStorageSync('udid') || '';
  if (udid_ == '') {
    udid_ = Math.floor(Math.random() * 89999999 + 10000000) + '' + Math.floor(Math.random() * 89999999 + 10000000);
    game.setStorageSync('udid', udid_);
  }
  return udid_;
};
game.cache = function(key, value) {
  if (typeof key != 'undefined' && typeof value != 'undefined') {
    return game.setStorageSync(key, value);
  } else if (typeof key != 'undefined') {
    return game.getStorageSync(key);
  }
};
game.getStorageSync = function(key) {
  if (game.inUniApp()) {
    return uni.getStorageSync(key);
  }
  return localStorage.getItem(key) || null;
};
game.setStorageSync = function(key, value) {
  if (game.inUniApp()) {
    return uni.setStorageSync(key, value);
  }
  localStorage.setItem(key, value);
};
let postList = {};
let postIng = false;
game.request = function(postdata) {

  return new Promise((resolve, reject) => {
    postList[Math.random() + ''] = [postdata, function(res) {
      resolve(res);
    }];
    game.postOnce();
  });
};
game.setData = function(data) {
  if (!data) {
    return;
  }
  for (var k in data) {
    game.global[k] = data[k];
    game.$emit('global-update', {
      key: k,
      value: data[k]
    });
  }
};
game.$emit = function(name, data) {
  if (game.inUniApp()) {
    return uni.$emit(name, data);
  }
  var myEvent = new CustomEvent(name, {
    detail: data
  });
  document.dispatchEvent(myEvent);
};
game.$on = function(name, func) {
  if (game.inUniApp()) {
    return uni.$on(name, func);
  }
  document.addEventListener(name, func, false);
};
game.$off = function(name, func) {
  if (game.inUniApp()) {
    return uni.$off(name, func);
  }
  document.removeEventListener(name, func, false);
};
game.post = function(request) {
  if (game.inUniApp()) {
    return uni.request(request);
  }
  var ajax;
  try {
    // Firefox, Opera 8.0+, Safari
    ajax = new XMLHttpRequest();
  } catch (e) {
    // Internet Explorer
    try {
      ajax = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        ajax = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {
        alert("您的浏览器不支持AJAX！");
        return false;
      }
    }
  }
  ajax.open("post", request.url, true);
  ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  ajax.onreadystatechange = function() {
    if (ajax.readyState == 4) {
      if (ajax.status == 200) {
        if (request.success) {
          request.success({
            data: JSON.parse(ajax.responseText)
          });
        }
      } else {
        if (request.fail) {
          request.fail({
            error: ajax.status
          });
        }
      }
    } else {

    }
  }
  ajax.send('postData=' + encodeURIComponent(request.data.postData));
};
game.postOnce = function() {
  if (postIng) {
    return;
  }
  postIng = true;
  setTimeout(function() {
    var postdatas = {};
    for (var k in postList) {
      postdatas[k] = postList[k][0];
    }
    var contentType = 'application/json';
    var data = {
      action: '$post',
      udid: game.udid(),
      req: postdatas
    };
    // #ifdef H5
    contentType = 'application/x-www-form-urlencoded';
    data = {
      postData: JSON.stringify(data)
    };
    // #endif
    game.post({
      url: game.apiurl,
      method: 'POST',
      data: data,
      header: {
        'content-type': contentType
      },
      success: function(res) {
        if (res.data.error) {
          game.alert(res.data.error);
          for (var k in postdatas) {
            delete postList[k];
            delete postdatas[k];
          }
        }
        if (res.data.results) {
          for (var k in res.data.results) {
            if (postList[k]) {
              try {
                postList[k][1](res.data.results[k]);
              } catch (e) {
                console.log(e);
              }
              delete postList[k];
              delete postdatas[k];
            }
          }
        }
        for (var k in postdatas) {
          postList[k][1]({
            status: 'error',
            error: 'no data'
          });
          delete postList[k];
          delete postdatas[k];
        }
        postIng = false;
        for (var k in postList) {
          setTimeout(game.postOnce, 100);
          break;
        }
      },
      fail: function(res) {
        for (var k in postdatas) {
          delete postList[k];
          delete postdatas[k];
        }
        postIng = false;
        for (var k in postList) {
          setTimeout(onez.postOnce, 100);
          break;
        }
      }
    });
  }, 100);
};
let _resize = [];

function onResize() {
  for (var i = 0; i < _resize.length; i++) {
    if (_resize[i]) {
      _resize[i]();
    }
  }
}
game.onResize = function(callback) {
  if (!callback) {
    return;
  }
  if (_resize.length == 0) {
    if (game.inUniApp()) {
      if (uni.onWindowResize) {
        uni.onWindowResize(onResize);
      }
    } else {
      window.onresize = onResize;
    }
  }
  _resize.push(callback);
  setTimeout(callback);
};
game.getSystemInfoSync = async function() {
  if (game.inUniApp()) {
    return uni.getSystemInfoSync();
  } else {
    let info = {};
    let el = game.$el || '#app';
    let box = document.querySelector(el);
    if (box) {
      await game.delay(0.5);
      info.windowWidth = box.offsetWidth;
      info.windowHeight = box.offsetHeight;
    } else {
      info.windowWidth = document.body.clientWidth || document.body.scrollWidth || window.screen.width;
      info.windowHeight = document.body.clientHeight || document.body.scrollHeight || window.screen.height;
    }
    return info;
  }
};
game.error = function(tip) {
  game.alert(tip);
};
game.stage = function() {
  return game.$stage;
};
//重新运行游戏
game.restart = async function() {
  game.$stage.restart();
};
game.alert = async function(content) {
  let data = {
    title: '系统提示'
  };
  data.message = content;
  if (!game.$stage) {
    console.warn(content);
    return;
  }
  // console.warn(game.$stage, data)
  return await game.$stage.dialog('message', data);
};
game.confirm = async function(content) {
  let data = {
    title: '系统提示'
  };
  data.method = 'confirm';
  data.message = content;
  return await game.$stage.dialog('message', data);
};
let loadingBegin = 0;
game.loading = async function(show) {
  if (show) {
    loadingBegin = (new Date()).getTime();
    game.$stage.showLoading();
    setTimeout(() => {
      if (loadingBegin != 0) {
        game.loading(false)
      }
    }, 5000);
  } else {
    let sec = (new Date()).getTime() - loadingBegin;
    if (sec < 500) {
      await game.delay(0.5 - sec * 0.001);
    }
    game.$stage.hideLoading();
    loadingBegin = 0;
  }
};
let ways = {};
game.load = function(way) {
  way.$game = game;
  ways[way.name] = way;
  game.gameName = way.name;
};
game.uid = function() {
  if (game.global.userid) {
    return game.global.userid;
  } else {
    return 'guest' + game.udid();
  }
};
game.isMe = function(uid) {
  return uid == game.uid();
};
game.hook = async function(that, method, request) {
  if (method == 'start') {
    game.global.userid = game.cache('userid');
    game.global.userToken = null;
    game.global.user = null;
    if (game.global.userid) {
      game.global.userToken = game.cache('userToken');
      game.global.user = await game.call('player', {
        userid: game.uid()
      });
      if (game.global.user.error) {
        game.global.userid = null;
        game.global.userToken = null;
        game.global.user = null;
      }
    }
    game.$stage = that;
  } else if (method == 'scene_after') {
    game.$stage.sceneReady(that);
  }
  let way = ways[game.gameName];
  if (way[method]) {
    return await way[method](that, request);
  }
};
game.login = async function() {
  let data = {
    title: '用户登录'
  };
  var form = [];
  form.push({
    label: '登录账号',
    key: 'username',
    notempty: '请填写您的登录账号'
  });
  form.push({
    label: '登录密码',
    type: 'password',
    key: 'password',
    notempty: '请填写您的登录密码'
  });
  data.form = form;
  data.width = 320;
  data.height = 240;
  data.noscroll = true;
  data.callback = async function(e) {
    var r = await game.call('login', e.values);
    if (r.error) {
      game.alert(r.error);
    } else {
      game.global.userid = r.userid;
      game.global.userToken = r.token;
      game.cache('userid', game.global.userid);
      game.cache('userToken', game.global.userToken);
      game.global.user = await game.call('user', {
        userid: game.global.userid
      });
      game.restart();
      return true;
    }
  };
  return await game.$stage.dialog('dialog', data);
};
game.register = async function() {
  let data = {
    title: '注册新账号'
  };
  var form = [];
  form.push({
    label: '登录账号',
    key: 'username',
    notempty: '请填写您的登录账号'
  });
  form.push({
    label: '登录密码',
    type: 'password',
    key: 'password',
    notempty: '请填写您的登录密码'
  });
  form.push({
    label: '确认密码',
    type: 'password',
    key: 'password2',
    notempty: '请再次填写您的登录密码'
  });
  data.form = form;
  data.width = 320;
  data.height = 280;
  data.noscroll = true;
  data.callback = async function(e) {
    if (e.values.password != e.values.password2) {
      game.alert('两次密码不一致');
      return;
    }
    var r = await game.call('register', e.values);
    if (r.error) {
      game.alert(r.error);
    } else {
      game.global.userid = r.userid;
      game.global.userToken = r.token;
      game.cache('userid', game.global.userid);
      game.cache('userToken', game.global.userToken);
      game.global.user = await game.call('user', {
        userid: game.global.userid
      });
      game.restart();
      return true;
    }
  };
  return await game.$stage.dialog('dialog', data);
};
game.parse = async function(data) {
  if (!data) {
    return;
  }
  if (data.error) {
    game.alert(data.error);
    return false;
  }
  if (data.message) {
    game.alert(data.message);
  }
  return true;
};
game.formatPos = function(pos) {
  if (!pos) {
    return [-1, -1];
  }
  if (typeof pos == 'string') {
    let t = pos.split(',');
    pos = [parseInt(t[0]), parseInt(t[1])];
  }
  if (isNaN(pos[0])) {
    pos[0] = 0;
  }
  if (isNaN(pos[1])) {
    pos[1] = 0;
  }
  return pos;
};
game.global = {};
game.sendMsg = async function(that, event) {
  console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~~.game.socket_scene', game.socket_scene, event);
  if (game.socket_scene) {
    game.socket_scene.emit('sendmsg', event);
  }
};
game.onEvent = async function(that, event) {
  console.log('onEvent', event);
  if (!event) {
    return;
  }
  if (event.callback) {
    return await event.callback();
  }
  if (!event.action) {
    return;
  }
  if (event.confirm) {
    var r = await game.confirm(event.confirm);
    if (!r) {
      return;
    }
  }
  if (event.action == 'login') {
    game.login();
  } else if (event.action == 'register') {
    game.register();
  } else if (event.action == 'menu') {
    game.menuKey = event.menuKey || 'page:' + event.page;
    game.$emit('menu-change', event);

  } else if (event.action == 'goTo') {
    let values = {};
    if (event.scene) {
      values.scene = event.scene;
    }
    if (event.pos) {
      if (typeof event.pos == 'object') {
        values.pos = event.pos;
      } else {
        let o = event.pos.split(',');
        let pos = [parseInt(o[0]), parseInt(o[1])];
        if (!isNaN(pos[0]) && !isNaN(pos[0])) {
          values.pos = pos;
        }
      }
    }
    let r = await game.call('data', {
      type: 'table',
      method: 'update',
      table: 'player',
      values: values,
      where: {
        userid: game.global.userid
      }
    });
    game.$stage.changeScene(values.scene, event.pos);
  } else if (event.action == 'submit') {
    let postdata = {
      type: 'submit'
    };
    if (event.page) {
      postdata.page = event.page;
    } else if (game.menuKey && game.menuKey.indexOf('page:') == 0) {
      postdata.page = game.menuKey.substr(5);
    } else {
      postdata.page = 'doit';
    }
    let r = await game.call('page', postdata);
    game.parse(r);
  } else if (event.action == 'event') {
    game.$emit('game-event', event);
  } else if (event.action == 'data') {
    game.loading(true);
    let r = await game.call('data', event.$data);
    game.loading(false);
    game.parse(r);
  } else if (event.action == 'page') {
    let r = await game.call('page', {
      page: event.page
    });
    if (!r) {
      game.alert('无效请求');
      return;
    }
    if (r.error) {
      game.alert(r.error);
    } else if (r.data) {
      if (r.data.submit) {
        r.data.callback = async function(e) {
          var r = await game.call('page', {
            action: r.data.submit,
            page: event.page,
            values: e.values
          });
          return await game.parse(r);
        };
      }
      r.data.$page = event.page;
      return await game.$stage.dialog('page', r.data);
    }
  }
  if (event.next) {
    return game.onEvent(that, event.next);
  }
};
//console.log('inUniApp',game.inUniApp()?'true':'false');
export default game;
